package cn.cdeden.job.snailjob.snailjob.service;

import org.springframework.stereotype.Component;

import javax.naming.Context;
import javax.naming.NamingException;
import javax.naming.directory.Attribute;
import javax.naming.directory.SearchResult;
import javax.naming.ldap.InitialLdapContext;
import javax.naming.ldap.LdapContext;
import java.util.Hashtable;
import java.util.Map;

@Component
public class LdapSevice {

    private static final String AD_DOMAIN_URL_KEY = "ad_domain_url";
    private static final String AD_DOMAIN_USERDN = "ad_domain_userDn";
    private static final String AD_DOMAIN_PASSWORD = "ad_domain_password";
    private static final String LDAP_FACTORY = "com.sun.jndi.ldap.LdapCtxFactory";
    private static final String LDAP_AUTH_METHOD = "simple";

    /**
     * 连接到LDAP服务器并返回一个LdapContext对象。
     *
     * @param config LdapConfig对象，包含连接LDAP服务器所需的配置信息
     * @return LdapContext对象，用于后续的LDAP操作
     * @throws NamingException 如果连接过程中发生异常，将抛出NamingException
     */
    public LdapContext ldapConnect(Map<String, String> config) {
//        SynchronousConfig config = synchronousConfigService.getById("1"); //此处是ad域的连接配置信息
        String username = config.get(AD_DOMAIN_USERDN);
        String server = config.get(AD_DOMAIN_URL_KEY);
        try {
            Hashtable<String, String> env = new Hashtable<>();
            //用户名称，cn,ou,dc 分别：用户，组，域
            env.put(Context.SECURITY_PRINCIPAL, username);
            //用户密码 cn 的密码
            env.put(Context.SECURITY_CREDENTIALS, config.get(AD_DOMAIN_PASSWORD));
            //url 格式：协议://ip:端口/组,域   ,直接连接到域或者组上面
            env.put(Context.PROVIDER_URL, server);
            //LDAP 工厂
            env.put(Context.INITIAL_CONTEXT_FACTORY, LDAP_FACTORY);
            //验证的类型     "none", "simple", "strong"
            env.put(Context.SECURITY_AUTHENTICATION, LDAP_AUTH_METHOD);
            env.put("java.naming.ldap.attributes.binary", "objectGUID");
            //协议
//            env.put(Context.SECURITY_PROTOCOL, "ssl");
            LdapContext ldapContext = new InitialLdapContext(env, null); //在类中定义了常量来保存连接后的内容以便后续使用

            return ldapContext;
        } catch (Exception e) {
            System.out.println("ldapConnect NamingException : " + e);
            return null;
        }
    }

    /**
     * 根据规范名称获取属性值
     *
     * @param sr          搜索结果对象
     * @param canonicalName 规范名称
     * @return 对应的属性值，如果未找到则返回null
     */
    public String getAttrValue(SearchResult sr, String canonicalName) {
        Attribute attribute = sr.getAttributes().get(canonicalName);
        if (attribute != null) {
            try {
                String s = attribute.get(0).toString();
                return s;
            } catch (NamingException e) {
                return null;
            }
        }
        return null;
    }

}
